package com.chouren.goandroid.img;

import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

import android.graphics.Bitmap;
import android.util.Log;

public class MemoryCache {
	private Map<String, Bitmap> cache = Collections.synchronizedMap(
			new LinkedHashMap<String, Bitmap>(10, 1.5f, true));
	// 缓存中图片所占用的字节，初始0，将通过此变量严格控制缓存所占用的堆内存
	private long size = 0;
	// 缓存能占用的最大堆内存
	private long limit = 1000000;
	
	public MemoryCache() {
		// 设置最大的缓存使用为能使用内存的25%
		setLimit(Runtime.getRuntime().maxMemory()/10);
	}
	
	public void setLimit(long limit) {
		this.limit = limit;
		Log.w("MemoryCache", "memory cache of image will set to : " + limit / 1024 /1024 + "MB");
	}
	
	public Bitmap getCache(String key) {
		if(key == null || "".equals(key)) {
			Log.e("MemoryCache", "parameter key is null");
			return null;
		}
		
		if(cache.containsKey(key)) {
			return cache.get(key);
		}else {
			return null;
		}
	}
	
	public void put(String key, Bitmap bitmap) {
		if(key == null || bitmap == null) {
			Log.e("MemoryCache", "parameter cannot be null");
			return;
		}
		if(cache.containsKey(key)) {
			return;
		}else {
			cache.put(key, bitmap);
			size += getSizeInBytes(bitmap);
			checkCacheSize();
		}
	}
	
	public void clear() {
		cache.clear();
	}
	
	public void checkCacheSize() {
		Log.w("MemoryCache", "check cache...");
		Log.w("MemoryCache", "cache map size : " + size + " ,map length : "+ cache.size());
		if(size >= limit) {
			Iterator<Entry<String, Bitmap>> iter = cache.entrySet().iterator();
			while (iter.hasNext()) {
				Entry<String, Bitmap> entry = iter.next();
				size -= getSizeInBytes(entry.getValue());
				iter.remove();
				if (size < limit)
					break;
			}
			Log.w("MemoryCache", "Clean cache. New size " + cache.size());
		}
		
	}
	
	public long getSizeInBytes(Bitmap bitmap) {
		if(bitmap == null) {
			Log.e("MemoryCache", "parameter bitmap is null");
			return -1;
		}
		return bitmap.getRowBytes() * bitmap.getHeight();
	}
}
